<template>
  <div class="terminal-container">
    <div class="terminal" ref="terminal"></div>
  </div>
</template>

<script>
import 'xterm/css/xterm.css';
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import { ElMessage } from 'element-plus';

export default {
  name: 'Terminal',
  props: ['url', 'singleId'],
  data() {
    return {
      term: null,
      socket: null,
      id: 0,
      centerDialogVisible: true,
      loading: false,
    };
  },
  mounted() {
    let query = this.$route.query;
    this.id = query.id;
    this.term = new Terminal({
      cursorBlink: true,
      lineHeight: 1.5,
      rows: 18,
    });

    const fitAddon = new FitAddon();
    this.term.loadAddon(fitAddon);
    fitAddon.fit();

    this.term.open(this.$refs.terminal);

    let url = this.url
      ? this.url
      : import.meta.env.MODE === 'development'
      ? `ws://172.17.0.29:12001/simulation/res/container/docker/${this.singleId}/console/`
      : `wss://${origin}/api/simulation/res/container/docker/${this.singleId}/console/`;
    this.socket = new WebSocket(`${url}`);

    this.socket.addEventListener('open', function (event) {
      this.loading = false;
    });

    this.socket.addEventListener('message', event => {
      const message = event.data;
      if (message === 'Docker Websocket Connection Failed!') {
        ElMessage.error('控制台打开失败，请查看日志');
        window.parent.postMessage(message, '*');
        return;
      }
      this.term.write(message);
      this.loading = false;
    });

    this.socket.onerror = error => {
      ElMessage({
        showClose: true,
        message: '未连接到控制台',
        type: 'error',
      });
      const ndata = false;
      window.parent.postMessage(ndata, '*');
      this.loading = false;
    };

    this.term.onData(data => {
      this.socket.send(data);
    });

    document.addEventListener('keydown', event => {
      if (event.ctrlKey && event.key === 'c') {
        document.execCommand('copy');
      }

      if (event.ctrlKey && event.key === 'v') {
        document.execCommand('paste');
      }
    });

    let commandHistory = [];
    let currentCommandIndex = -1;

    this.term.onKey(e => {
      const printable =
        !e.domEvent.altKey &&
        !e.domEvent.altGraphKey &&
        !e.domEvent.ctrlKey &&
        !e.domEvent.metaKey;

      if (e.key === 'Enter') {
        const command = this.term.buffer
          .getLine(this.term.buffer.cursorY)
          .trim();
        if (command !== '') {
          commandHistory.unshift(command);
          currentCommandIndex = -1;

          this.socket.send(command + '\n');
        }

        this.term.write('\n\r');
        this.term.write('$ ');
      } else if (e.key === 'Backspace') {
        if (this.term.buffer.cursorX > 2) {
          this.term.write('\b \b');
        }
      } else if (e.key === 'ArrowUp') {
        if (commandHistory.length > 0) {
          if (currentCommandIndex === -1) {
            currentCommandIndex = 0;
            this.term.write('\r\n$ ' + commandHistory[currentCommandIndex]);
          } else if (currentCommandIndex < commandHistory.length - 1) {
            currentCommandIndex++;
            this.eraseInputLine();
            this.term.write('$ ' + commandHistory[currentCommandIndex]);
          }
        }
      } else if (e.key === 'ArrowDown') {
        if (commandHistory.length > 0) {
          if (currentCommandIndex > 0) {
            currentCommandIndex--;
            this.eraseInputLine();
            this.term.write('$ ' + commandHistory[currentCommandIndex]);
          } else if (currentCommandIndex === 0) {
            currentCommandIndex = -1;
            this.eraseInputLine();
          }
        }
      } else if (printable) {
        // this.term.write(e.key)
      }
    });

    this.term.write('$ ');
  },
  beforeDestroy() {
    this.socket = null;
  },
  methods: {
    eraseInputLine() {
      while (this.term.buffer.cursorX > 2) {
        this.term.write('\b \b');
      }
    },
  },
};
</script>

<style scoped>
.terminal-container {
  height: 100%;
  width: 100%;
}

.terminal {
  height: 100%;
  width: 100%;
  padding: 0 0 0 12px;
  background-color: #000;
}
</style>
<style>
.xterm-screen,
.xterm {
  /* min-height: calc(100vh); */
  height: 100%;
}

.xterm-rows div {
  font-size: inherit;
  font-family: inherit;
}
</style>
<style scoped>
h1,
h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
